#ifndef H_BLINN_PHONG_INCLUDED
#define H_BLINN_PHONG_INCLUDED

struct BlinnPhongProperty
{
    half3 diffuseColor;
    half3 specularColor;
    float shininess;
};

struct BlinnPhongGeo
{
    float3 normal;
    float3 viewDir;
    float3 position;
};

float LambertDiffuse(float3 normal,float3 lightDir)
{
    return max(0, dot(normal, lightDir));
}

float BlinnPhongSpecular(float3 viewDir, float3 normal, float3 lightDir, float shininess)
{
    float3 halfDir = normalize((viewDir  + lightDir));
    float nh = max(0, dot(halfDir, normal));
    return pow(nh, shininess);
}

half4 BlinnPhong(float3 lightDir, BlinnPhongGeo geo, BlinnPhongProperty property)
{
    half3 diffuse = LambertDiffuse(geo.normal,lightDir) * property.diffuseColor;
    half3 specular = BlinnPhongSpecular(geo.viewDir, geo.normal,lightDir,property.shininess) * property.specularColor;
    return half4(diffuse + specular, 1);
}

#endif